using UnityEngine;
using UnityEditor;
using System.Collections;
using DICE_GS;

public class BoardIndex
{
	public int x;
	public int y;
	
	public BoardIndex()
	{
		x=-1;
		y=-1;
	}
	
	public BoardIndex(int _x, int _y)
	{
		x = _x;
		y = _y;
	}
}

[CustomEditor (typeof(BoardTile))]

public class BoardTileEditor : Editor
{
	BoardTile selectedBoardTile;
	static BoardTile [,] boardTiles;
	static BoardIndex [] boardIdIndex;
	static PathManager pathManager;
	
	string boardIdStr;
	Texture2D upTex;
	Texture2D downTex;
	Texture2D leftTex;
	Texture2D rightTex;
	private Vector3 mouseHitPos;
	
	static int max_grid_x = 500;
	static int max_grid_y = 500;
	Vector3 [,] gridTilePos;
	int curpath;
	int setPathCount=0;
	
	void UpdateHitPosition()
	{
		Plane p = new Plane( (this.target as MonoBehaviour).transform.TransformDirection(Vector3.forward),  new Vector3(0,0,1) );
		Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
		Vector3 hit = new Vector3();
		   float dist;
		if (p.Raycast(ray, out dist))
			hit = ray.origin + ray.direction.normalized * dist;
		mouseHitPos = (this.target as MonoBehaviour).transform.InverseTransformPoint(hit);
	}
	
	void OnSceneGUI()
	{
		//UpdateHitPosition();
		//Debug.Log ("mouse hi pos="+mouseHitPos);
		
		Event current = Event.current;
		if (current.Equals(Event.KeyboardEvent("a")))
		{
			setPathCount=0;
			SetPath(selectedBoardTile,0,-1,false);//left
		}
		if (current.Equals(Event.KeyboardEvent("d")))
		{
			setPathCount=0;
			SetPath(selectedBoardTile,0,1,false);//right
		}
		if (current.Equals(Event.KeyboardEvent("w")))
		{
			setPathCount=0;
			SetPath(selectedBoardTile,-1,0,false);//up
		}
		if (current.Equals(Event.KeyboardEvent("s")))
		{
			setPathCount=0;
			SetPath(selectedBoardTile,1,0,false);//down
		}
		
		if (current.Equals(Event.KeyboardEvent("#a")))
		{
			setPathCount=0;
			DeletePath(0,-1,true);//left
		}
		if (current.Equals(Event.KeyboardEvent("#d")))
		{
			setPathCount=0;
			DeletePath(0,1,true);//right
		}
		if (current.Equals(Event.KeyboardEvent("#w")))
		{
			setPathCount=0;
			DeletePath(-1,0,true);//up
		}
		if (current.Equals(Event.KeyboardEvent("#s")))
		{
			setPathCount=0;
			DeletePath(1,0,true);//down
		}		
//		for(int y=0;y< boardTiles.GetUpperBound(1); y++)
//		{
//			for(int x=0;x< boardTiles.GetUpperBound(0); x++)
//			{pathInfo[curpath].backBoards
//				if( boardTiles[x,y] != null)
//				{
//					
//				}
//			}
//		}
		
		SceneGUI();
	}
	
	void SceneGUI()
	{
		Handles.BeginGUI();
		GUI.color = Color.black;
		GUI.Label(new Rect(10,10,100,100),"id= "+boardIdStr);
		if(selectedBoardTile!=null)
		{
			string forwardIdStr = "";
			foreach( int forwardId in selectedBoardTile.boardInfo.pathInfo[curpath].forwardBoards)
				forwardIdStr += forwardId.ToString() + " ";
			GUI.Label(new Rect(10,25,100,100),"forward= "+forwardIdStr);
			string backIdStr = "";
			foreach( int backId in selectedBoardTile.boardInfo.pathInfo[curpath].backBoards)
				backIdStr += backId.ToString() + " ";		
			GUI.Label(new Rect(10,40,100,100),"back= "+backIdStr);
		}
		GUI.Label(new Rect(10,Screen.height - 90,100,100),"a: path left");
		GUI.Label(new Rect(10,Screen.height - 75,100,100),"d: path right");
		GUI.Label(new Rect(10 + 90,Screen.height - 90,100,100),"w: path up");
		GUI.Label(new Rect(10 + 90,Screen.height - 75,100,100),"s: path down");
		GUI.Label(new Rect(10,Screen.height - 60,200,100),"shift + dir : delete path");
		//GUI.Label(new Rect(10,Screen.height - 75,100,100),"x: left/right path set");
		//GUI.Label(new Rect(10,Screen.height - 90,100,100),"Ctrl: Erase");
		//GUI.Label(new Rect(10,Screen.height - 105,100,100),"Shift: Draw");
		
		//textureToDisplay = new Texture2D(100,100);
		
		//textureToDisplay.SetPixel(0,0,new Color(0,0.5f,1f,0.4f));
		//textureToDisplay.Apply();
		Handles.EndGUI();
		
		if(boardTiles != null)
		{
			for(int y=1;y<= boardTiles.GetUpperBound(1); y++)
			{
				
				for(int x=1;x<= boardTiles.GetUpperBound(0); x++)
				{
					if( boardTiles[x,y] != null)
					{
						if(curpath==0)
							Handles.color = Color.cyan;
						else
							Handles.color = Color.magenta;
	            		//Handles.DrawWireDisc(boardTiles[x,y].transform.position, -Vector3.forward, 0.1f);
						foreach( int nextId in boardTiles[x,y].boardInfo.pathInfo[curpath].forwardBoards)
						{
							Vector3 nextPos = boardTiles[boardIdIndex[nextId].x, boardIdIndex[nextId].y].transform.position;
							//Handles.DrawLine(boardTiles[x,y].transform.position, nextPos);
							Vector3 relativePos = nextPos - boardTiles[x,y].transform.position;
							relativePos.z = 0;
        					Quaternion rotation = Quaternion.LookRotation(relativePos);
							float arrowSize = relativePos.magnitude;
							Vector3 pos = boardTiles[x,y].transform.position;
							pos.z=0;
							Handles.ArrowCap(0, pos, rotation, arrowSize*0.9f);
						}
						
					}
				}
			}			
		}
		/*
		if(selectedBoardTile!=null)
		{
			float sx = selectedBoardTile.transform.position.x;
			float sy = selectedBoardTile.transform.position.y;
			Vector3 newPos = GetGridPos(sx,sy);
			newPos.z = selectedBoardTile.transform.position.z;
			selectedBoardTile.transform.position = newPos;
		}*/
		//Debug.Log("selectedBoardTile.transform.position=  "+selectedBoardTile.transform.position);
	}	
	
	void OnEnable() 
	{
		if(pathManager==null)
		{
			GameObject pathMgrObj = GameObject.FindGameObjectWithTag("Path Manager");
			if(pathMgrObj!=null)
			{
				pathManager = pathMgrObj.GetComponent<PathManager>();
				if(pathManager!=null)
				{
					
					boardTiles = new BoardTile[pathManager.nMaxX, pathManager.nMaxY];
					boardIdIndex = new BoardIndex[pathManager.nMaxX * pathManager.nMaxY];
					GameObject [] boardObjs = GameObject.FindGameObjectsWithTag("Board Tile");
					foreach( GameObject obj in boardObjs)
					{
						BoardTile bt = obj.GetComponent<BoardTile>();
						if(bt!=null) {//bt is null case..why?
							boardTiles[bt.boardInfo.index_x, bt.boardInfo.index_y] = bt;
							boardIdIndex[bt.boardInfo.id] = new BoardIndex(bt.boardInfo.index_x, bt.boardInfo.index_y);
						}
					}			
					Debug.Log("OnEnable init once");
				}
			}
//			upTex = (Texture2D) AssetDatabase.LoadAssetAtPath("Assets/TheDice/Sprite/uparrow.png", typeof(Texture2D) );
//			downTex = (Texture2D) AssetDatabase.LoadAssetAtPath("Assets/TheDice/Sprite/downarrow.png", typeof(Texture2D) );
//			leftTex = (Texture2D) AssetDatabase.LoadAssetAtPath("Assets/TheDice/Sprite/leftarrow.png", typeof(Texture2D) );
//			rightTex = (Texture2D) AssetDatabase.LoadAssetAtPath("Assets/TheDice/Sprite/rightarrow.png", typeof(Texture2D) );
		}
		curpath = pathManager.curPathCount;
		gridTilePos = new Vector3[max_grid_x,max_grid_y];
		float step_x = 0.3185672f;
		float step_y = 0.1613847f;
		float step_z = 0.0001f;
		float tz = 0;
		int halfGridX = max_grid_x/2;
		int halfGridY = max_grid_y/2;
		for(int y=0; y<max_grid_y; y++)
		{
			for(int x=0; x< max_grid_x; x++)
			{
				gridTilePos[x,y] = new Vector3( (x-halfGridX)*step_x, (y-halfGridY)*step_y, tz);
			}
			tz += step_z;
		}
		
		
		selectedBoardTile = target as BoardTile;
		boardIdStr = selectedBoardTile.boardInfo.id.ToString();
	}
	
	Vector3 GetGridPos(float sx, float sy)
	{
		for(int y=0; y<max_grid_y; y++)
		{
			for(int x=0; x< max_grid_x-1; x++)
			{
				if(sx>gridTilePos[x,y].x+0.01f && sx<gridTilePos[x+1,y].x-0.01f && sy>gridTilePos[x,y].y+0.01f && sy<gridTilePos[x,y+1].y-0.01f)
					return gridTilePos[x,y];
			}
		}		
		return new Vector3(sx,sy,0);
	}
	
	public bool HasTile(int x, int y)
	{
		if(x<0 || y<0)
			return false;
		if(x>= pathManager.nMaxX || y>= pathManager.nMaxY)
			return false;
		
		if( boardTiles[x,y] != null)
			return true;
		return false;
	}
	
	void SetPath_old(int nUp, int nRight, bool bDelete)
	{
		int i = nRight;
		int j = nUp;	
		
		int ix = selectedBoardTile.boardInfo.index_x;
		int iy = selectedBoardTile.boardInfo.index_y;
		
		while(true)
		{
			if( !HasTile(ix+i,iy+j) )
				break;
			int idToAdd = boardTiles[ix,iy].boardInfo.id;
			if( !boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].backBoards.Contains(idToAdd ) && !boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].forwardBoards.Contains( idToAdd))
				boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].backBoards.Add( idToAdd );
			if(bDelete)
				boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].backBoards.Clear();
			idToAdd = boardTiles[ix+i,iy+j].boardInfo.id;
			if( !boardTiles[ix,iy].boardInfo.pathInfo[curpath].forwardBoards.Contains( idToAdd) && !boardTiles[ix,iy].boardInfo.pathInfo[curpath].backBoards.Contains(idToAdd) )
				boardTiles[ix,iy].boardInfo.pathInfo[curpath].forwardBoards.Add( idToAdd);
			if(bDelete)
				boardTiles[ix,iy].boardInfo.pathInfo[curpath].forwardBoards.Clear();
			
			ix += i;
			iy += j;
		}
	}	

	void DeletePath(int nUp, int nRight, bool bDelete)
	{
		int i = nRight;
		int j = nUp;	
		
		int ix = selectedBoardTile.boardInfo.index_x;
		int iy = selectedBoardTile.boardInfo.index_y;
		
		while(true)
		{
			if( !HasTile(ix+i,iy+j) )
				break;
			int idToAdd = boardTiles[ix,iy].boardInfo.id;
			if( !boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].backBoards.Contains(idToAdd ) && !boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].forwardBoards.Contains( idToAdd))
				boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].backBoards.Add( idToAdd );
			if(bDelete)
				boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].backBoards.Clear();
			idToAdd = boardTiles[ix+i,iy+j].boardInfo.id;
			if( !boardTiles[ix,iy].boardInfo.pathInfo[curpath].forwardBoards.Contains( idToAdd) && !boardTiles[ix,iy].boardInfo.pathInfo[curpath].backBoards.Contains(idToAdd) )
				boardTiles[ix,iy].boardInfo.pathInfo[curpath].forwardBoards.Add( idToAdd);
			if(bDelete)
				boardTiles[ix,iy].boardInfo.pathInfo[curpath].forwardBoards.Clear();
			
			ix += i;
			iy += j;
		}
	}	
	
	void SetPath(BoardTile bt , int nUp, int nRight, bool bDelete)
	{
		setPathCount++;
		int i = nRight;
		int j = nUp;	
		
		int ix = bt.boardInfo.index_x;
		int iy = bt.boardInfo.index_y;
		
		if(setPathCount>1 && (bt.boardInfo.isGoal || bt.boardInfo.isStart)  )
			return;
		while(true)
		{
			if( !HasTile(ix+i,iy+j) )
			{
				if(i!=0)
				{
					if( HasTile(ix,iy+1) && HasTile(ix,iy-1) )
						break;
					if( HasTile(ix,iy+1) )
						SetPath(boardTiles[ix,iy], 1,0 ,bDelete);
					if( HasTile(ix,iy-1) )
						SetPath(boardTiles[ix,iy], -1,0 ,bDelete);
				}
				else if(j!=0)
				{
					if( HasTile(ix+1,iy) && HasTile(ix-1,iy) )
						break;
					if( HasTile(ix+1,iy) )
						SetPath(boardTiles[ix,iy], 0,1 ,bDelete);
					if( HasTile(ix-1,iy) )
						SetPath(boardTiles[ix,iy], 0,-1 ,bDelete);					
				}
				
			}
			else
			{
				if(setPathCount>1)
				{
					if(i!=0)
					{
						if( ( HasTile(ix,iy+1) && boardTiles[ix,iy+1].boardInfo.pathInfo[curpath].forwardBoards.Count==0 ) || 
							( HasTile(ix,iy-1) && boardTiles[ix,iy-1].boardInfo.pathInfo[curpath].forwardBoards.Count==0 )    )  
							break;
					}
					else if(j!=0)
					{
						if( ( HasTile(ix+1,iy) && boardTiles[ix+1,iy].boardInfo.pathInfo[curpath].forwardBoards.Count==0 ) || 
							( HasTile(ix-1,iy) && boardTiles[ix-1,iy].boardInfo.pathInfo[curpath].forwardBoards.Count==0 )    )  
							break;					
					}	
				}
			}
			
			if( !HasTile(ix+i,iy+j) )
				break;
//			if( boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].forwardBoards.Count>0)
//			{
//				break;
//			}
			
			int idToAdd = boardTiles[ix,iy].boardInfo.id;
			if( !boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].backBoards.Contains(idToAdd ) && !boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].forwardBoards.Contains( idToAdd))
				boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].backBoards.Add( idToAdd );
			else
			{
//				break;
			}
			
			if(bDelete)
				boardTiles[ix+i,iy+j].boardInfo.pathInfo[curpath].backBoards.Clear();
			
			idToAdd = boardTiles[ix+i,iy+j].boardInfo.id;
			
			if( !boardTiles[ix,iy].boardInfo.pathInfo[curpath].forwardBoards.Contains( idToAdd) && !boardTiles[ix,iy].boardInfo.pathInfo[curpath].backBoards.Contains(idToAdd) )
				boardTiles[ix,iy].boardInfo.pathInfo[curpath].forwardBoards.Add( idToAdd);
			else
			{
//				break;
			}
			
			if(bDelete)
				boardTiles[ix,iy].boardInfo.pathInfo[curpath].forwardBoards.Clear();
			
			ix += i;
			iy += j;
		}
	}	
}